package game.event;

import game.Field;
import game.Food;
import game.Point;
import game.connection.GameEvent;

import java.util.HashMap;
import java.util.Map;

/**
 * This class manage the game event.
 * 
 * @author Sarun Wongtanakarn 5510546166
 * @author Apiwat Jierakulpanit 5510546212
 * @Version 2013.04.27
 */
public class Referee {

	/** The head of snake. */
	private Point head;
	/** The tail of snake. */
	private Point tail;
	/** The field in server. */
	private Field field;
	/** The event that will be decided. */
	private GameEvent incomingEvent;
	/** The id of player who is owns of event. */
	private int id;
	/** The number of max player in game. */
	private int maxPlayer;
	
	/** The result event for return to server. */
	private Map<Integer, GameEvent> gameResult;

	/**
	 * Decides the incoming event and design the result event.
	 * 
	 * @param incomingEvent the event that come to referee
	 * @param field field in server
	 * @param id the id of player who is owns of incoming event
	 * @param maxplayer number of maxplayer in game
	 * @param food the food in server
	 */
	public Map<Integer, GameEvent> handleEvent(GameEvent incomingEvent,
			Field field, int id, int maxPlayer, Food food) {
		this.maxPlayer = maxPlayer;
			this.field = field;
			this.incomingEvent = incomingEvent;
			this.id = id;

			defineHeadAndTail();

			gameResult = new HashMap<Integer, GameEvent>();
			HealthEvent decrease = new HealthEvent();
			//decrease.addEvent(-1);
			for (int i = 1; i <= maxPlayer; i++) {
				gameResult.put(i, new GameEvent());
				gameResult.get(i).addStatusEvent(decrease);
			}

			
			if (field.getValue(head) == 9) {
				gameResult.get(id).growth();
				MoneyEvent addMoney = new MoneyEvent();
				addMoney.addEvent(100);
				gameResult.get(id).addStatusEvent(addMoney);
				move();
				HealthEvent addHP = new HealthEvent();
				addHP.addEvent(10);
				gameResult.get(id).addStatusEvent(addHP);
			} else if (field.getValue(head) == id) {
				System.out.println("you found yourself");
			} else if (field.getValue(head) != 0  && field.getValue(head) != 9) {
				bloodSucking(field.getValue(head));
				move();
			}
			else {
				move();
			}
			
			return gameResult;
		
	}

	/**
	 * Sets the new value of point in field.
	 * Add move event to result event.
	 */
	private void move() {
		field.setValue(head, id);
		field.setValue(tail, 0);
		for (int i = 1; i <= maxPlayer; i++) {
			gameResult.get(i).addMoveEvent(head, id);
			gameResult.get(i).addMoveEvent(tail, 0);
		}
		
	}

	/** 
	 * Increase health to the owner of incoming event.
	 * Decrease health to the opponent player.
	 * @param opponentID the id of the opponent player
	 */
	private void bloodSucking(int opponentID) {
		HealthEvent addHP = new HealthEvent();
		addHP.addEvent(10);
		gameResult.get(id).addStatusEvent(addHP);
		
		HealthEvent removeHP = new HealthEvent();
		removeHP.addEvent(-10);
		gameResult.get(opponentID).addStatusEvent(removeHP);
	}

	/** Defines the head and tail of the snake of the incoming owner. */
	private void defineHeadAndTail() {
		for (Point c : incomingEvent.getMoveMap().keySet()) {
			if (field.getValue(c) != id
					&& incomingEvent.getMoveMap().get(c) == id) {
				head = c;
			}
			if (field.getValue(c) == id
					&& incomingEvent.getMoveMap().get(c) == 0) {
				tail = c;
			}
		}
	}


}
